﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.IO;
using System.Xml;
using System.Xml.XPath;
using Microsoft.SqlServer.Management.Smo;

using P2.Cuberry.Framework.BOLBase;
using P2.Cuberry.Framework.Helper;
using P2.Cuberry.Framework.Helper.Configuration;
using P2.Cuberry.Framework.Security;
using P2.Cuberry.Modules.Framework.ModuleManager.DAL;

namespace P2.Cuberry.Modules.Framework.ModuleManager.BusinessEntities
{
    public class ModulesImport : BizObject, INotifyPropertyChanged
    {
        const string SPACE_DOTS = "....";
        const string KEY_TABLE_CREATE = "Create";
        const string KEY_TABLE_ALTER = "Alter";
        const string KEY_TABLE_INSERT_DATA = "InsertData";
        const string KEY_TABLE_UPDATE_DATA = "UpdateData";

        readonly string TABLE_CREATION;
        readonly string TABLE_UPDATE;
        readonly string SP_CREATION;
        readonly string VIEW_CREATION;
        readonly string FUNCTION_CREATION;
        readonly string DATA_INSERT;
        readonly string DATA_UPDATION;
        readonly string KEEP_CURRENT;
        readonly string REPLACE;

        public ModulesImport()
        {
            TABLE_CREATION = P2Translator.GetResource("TableCreation"); //"Table Creation";
            TABLE_UPDATE = P2Translator.GetResource("TableUpdate"); //"Table Update";
            SP_CREATION = P2Translator.GetResource("SPCreation"); //"SP Creation";
            VIEW_CREATION = P2Translator.GetResource("ViewCreation"); //"View Creation";
            FUNCTION_CREATION = P2Translator.GetResource("FunctionCreation"); //"Function Creation";
            DATA_INSERT = P2Translator.GetResource("DataInsertion"); //"Data Insertion";
            DATA_UPDATION = P2Translator.GetResource("DataUpdation"); //"Data Updation";
            KEEP_CURRENT = P2Translator.GetResource("KeepCurrent"); //"Keep Current";
            REPLACE = P2Translator.GetResource("Replace");//"Replace";

            Modified = false;
            _actionList.Add(KEEP_CURRENT);
            _actionList.Add(REPLACE);
        }

        #region Members

        private static string ModulesLocation { get; set; }
        //private static string ModulesRepositoryType { get; set; }
        //private static string ModulesRepositoryPath { get; set; }

        private ObservableCollection<ModulesImport> _importList = new ObservableCollection<ModulesImport>();
        public ObservableCollection<ModulesImport> ImportList
        {
            get{return _importList;}
            private set{_importList = value;}
        }

        private List<string> _actionList = new List<string>();
        public List<string> ActionList
        {
            get { return _actionList; }
            set { _actionList = value; }
        }

        private Dictionary<string, string> _modulesXmlFileData = new Dictionary<string, string>();
        public Dictionary<string, string> ModulesXmlFileData
        {
            get { return _modulesXmlFileData; }
            set { _modulesXmlFileData = value; }
        }

        public static string TempFolderForCuberry { get; set; }

        public string ItemKey { get; set; }

        private string _itemName;
        public string ItemName
        {
            get { return _itemName; }
            set
            {
                if (value != _itemName)
                {
                    _itemName = value;
                    Modified = true;
                }
            }
        }

        private string _actionType;
        public string ActionType
        {
            get { return _actionType; }
            set
            {
                if (value != _actionType)
                {
                    _actionType = value;
                    Modified = true;
                }
            }
        }

        private string _actionToBeTaken;
        public string ActionToBeTaken
        {
            get { return _actionToBeTaken; }
            set
            {
                if (value != _actionToBeTaken)
                {
                    _actionToBeTaken = value;
                    Modified = true;
                    OnPropertyChanged("ActionToBeTaken");
                }
            }
        }

        private string _process;
        public string Process
        {
            get { return _process; }
            set
            {
                if (value != _process)
                {
                    _process = value;
                    Modified = true;
                    OnPropertyChanged("Process");
                }
            }
        }

        private string _statusImage = @"H:\Ennovations\Cuberry Framework\Cuberry 2012-02-25 SLN\Cuberry\CuberrySolution\P2.Cuberry.Modules.Framework.ModuleManager\Images\StatusNotStarted.png";
        public string StatusImage
        {
            get { return _statusImage; }
            set 
            { 
                _statusImage = value;
                OnPropertyChanged("StatusImage");
            }
        }

        private ImportItemStatus _importItemStatus = ImportItemStatus.NotValidated;
        public ImportItemStatus ItemValidationStatus
        {
            get { return _importItemStatus; }
            set { _importItemStatus = value; }
        }

        private ImportItemType _importItemType;
        public ImportItemType ItemType
        {
            get { return _importItemType; }
            set { _importItemType = value; }
        }

        public string FileFullName { get; set; }

        public string ItemModuleName { get; set; }

        public Module ParentModule { set; get; }

        #endregion

        //public void RetrieveParametersFromXAppConfig(ref string modulesLocation, ref string modulesRepositoryType, ref string modulesRepositoryPath)
        //{
        //    string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
        //    using (ModuleManagerDataContext db = new ModuleManagerDataContext(connectionString))
        //    {
        //        var configData = from tran in db.XAppConfig
        //                            select new { ConfigName = tran.ConfigName, ConfigValue = tran.ConfigValue };

        //        if (configData.Count() > 0)
        //        {
        //            modulesLocation = configData.Where(e => e.ConfigName.Trim().ToUpper() == "MODULESLOCATION").FirstOrDefault().ConfigValue;
        //            modulesRepositoryType = configData.Where(e => e.ConfigName.Trim().ToUpper() == "MODULESREPOSITORYTYPE").FirstOrDefault().ConfigValue;
        //            modulesRepositoryPath = configData.Where(e => e.ConfigName.Trim().ToUpper() == "MODULESREPOSITORYPATH").FirstOrDefault().ConfigValue;

        //            ModulesLocation = modulesLocation;
        //            ModulesRepositoryType = modulesRepositoryType;
        //            ModulesRepositoryPath = modulesRepositoryPath;
        //        }
        //    }
        //}

        public void ProcessCreateXMLFile(string fileName)
        {
            if (!File.Exists(fileName))
                return;

            XPathDocument xpathDocument = new XPathDocument(fileName);
            XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();

            XPathNodeIterator xpathTablesNodeIterator = xpathNavigator.Select("Schema//Tables//Create//Table");

            if (xpathTablesNodeIterator.Count == 0)
                return;

            //Create section
            while (xpathTablesNodeIterator.MoveNext())
            {
                var tableName = xpathTablesNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(tableName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = tableName, ActionType = TABLE_CREATION, ActionToBeTaken = KEEP_CURRENT, 
                                                    ItemType=ImportItemType.Xml, ItemKey = tableName + KEY_TABLE_CREATE });
            }

            //Alter section
            XPathNodeIterator xpathAlterTablesNodeIterator = xpathNavigator.Select("Schema//Tables//Alter//Table");

            while (xpathAlterTablesNodeIterator.MoveNext())
            {
                var tableName = xpathAlterTablesNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(tableName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = tableName, ActionType = TABLE_UPDATE, ActionToBeTaken = KEEP_CURRENT, 
                                                    ItemType = ImportItemType.Xml, ItemKey = tableName + KEY_TABLE_ALTER });
            }

            //Views section
            XPathNodeIterator xpathViewsNodeIterator = xpathNavigator.Select("Schema//Views//View");

            while (xpathViewsNodeIterator.MoveNext())
            {
                var viewName = xpathViewsNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(viewName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = viewName, ActionType = VIEW_CREATION, ActionToBeTaken = KEEP_CURRENT, 
                                                    ItemType = ImportItemType.Xml, ItemKey = viewName });
            }

            //SP section
            XPathNodeIterator xpathSPsNodeIterator = xpathNavigator.Select("Schema//StoredProcs/StoredProc");

            while (xpathSPsNodeIterator.MoveNext())
            {
                var spName = xpathSPsNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(spName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = spName, ActionType = SP_CREATION, ActionToBeTaken = KEEP_CURRENT, 
                                                    ItemType = ImportItemType.Xml, ItemKey = spName });
            }

            //Function section
            XPathNodeIterator xpathFuncsNodeIterator = xpathNavigator.Select("Schema//Functions//Function");

            while (xpathFuncsNodeIterator.MoveNext())
            {
                var functionName = xpathFuncsNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(functionName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = functionName, ActionType = FUNCTION_CREATION, ActionToBeTaken = KEEP_CURRENT, 
                                                    ItemType = ImportItemType.Xml, ItemKey = functionName });
            }
        }

        public void ProcessUpdateXMLFile(string fileName)
        {
            if (!File.Exists(fileName))
                return;

            XPathDocument xpathDocument = new XPathDocument(fileName);
            XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();

            XPathNodeIterator xpathInsertNodeIterator = xpathNavigator.Select("Data//Insert//Table");

            if (xpathInsertNodeIterator.Count == 0)
                return;

            //Insert section
            while (xpathInsertNodeIterator.MoveNext())
            {
                var tableName = xpathInsertNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(tableName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = tableName, ActionType = DATA_INSERT, ActionToBeTaken = "", 
                                                    ItemType = ImportItemType.Xml, ItemKey = tableName + KEY_TABLE_INSERT_DATA });
            }

            //Update section
            XPathNodeIterator xpathUpdateTablesNodeIterator = xpathNavigator.Select("Data//Update//Table");

            while (xpathUpdateTablesNodeIterator.MoveNext())
            {
                var tableName = xpathUpdateTablesNodeIterator.Current.GetAttribute("Name", "");
                if (string.IsNullOrEmpty(tableName))
                    continue;
                ImportList.Add(new ModulesImport() { ItemName = tableName, ActionType = DATA_UPDATION, ActionToBeTaken = "", 
                                                    ItemType = ImportItemType.Xml, ItemKey = tableName + KEY_TABLE_UPDATE_DATA });
            }
        }

        public bool PerformValidations(out bool isThereAnyConflit)
        {
            if (string.IsNullOrEmpty(TempFolderForCuberry))
                throw new FileNotFoundException("Seems you don't have sufficient rights. There is no file for validation");

            if (!Directory.Exists(TempFolderForCuberry))
                throw new FileNotFoundException(TempFolderForCuberry + " was not found. There is no file for validation");

            bool conflictFound = false;

            conflictFound = this.DoValidationForAssemblies();
            
            if (conflictFound)
                this.DoValidationForDBObjects();
            else
                conflictFound = this.DoValidationForDBObjects();

            isThereAnyConflit = conflictFound;

            return true;   
        }

        public bool ImportZipFileDataInCuberry()
        {
            this.ExtractDataFromModulesXmlFile();

            bool result = this.ImportAssemblyFiles();
            if (!result)
                return false;
            result = this.ImportDatabaseItems();
            return result;
        }

        private void ExtractDataFromModulesXmlFile()
        {
            

            if (!File.Exists(Path.Combine(TempFolderForCuberry, "Modules.xml")))
                return;

            ModulesXmlFileData.Clear();

            XPathDocument xpathDocument = new XPathDocument(Path.Combine(TempFolderForCuberry, "Modules.xml"));
            XPathNavigator xpathNavigator = xpathDocument.CreateNavigator();

            XPathNodeIterator moduleIterator = xpathNavigator.Select("//Modules//Module");

            if (moduleIterator.Count == 0)
                return;

            while (moduleIterator.MoveNext())
            {
                var dllName = moduleIterator.Current.GetAttribute("DllName", "");
                var moduleName = moduleIterator.Current.GetAttribute("ModuleName", "");

                if (string.IsNullOrEmpty(dllName) || string.IsNullOrEmpty(moduleName))
                    throw new MissingFieldException("Either dll name or module name was not defined in Modules xml file");

                ModulesXmlFileData.Add(dllName, moduleName);
            }

        }

        private bool ImportAssemblyFiles()
        {
            IEnumerable<ModulesImport> dllItems = ImportList.Where(e => e.ItemType == ImportItemType.Dll);

            List<XConfigModules> xConfigModulesCollection = null;
            string connectionString=string.Empty;

            if (P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath.Trim().ToUpper() == "DATABASE")
            {
                connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (ModuleManagerDataContext db = new ModuleManagerDataContext(connectionString))
                {
                    xConfigModulesCollection = (from tran in db.XConfigModules
                                      select tran).ToList();
                }
            }

            var backUpLocation = string.Empty;

            if (P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath.Trim().ToUpper() != "DATABASE")
            {
                backUpLocation = string.Empty;

                if (string.IsNullOrEmpty(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath))
                    throw new MissingFieldException("Modules Repository Path was not defined in DB configuration");

                backUpLocation = Path.Combine(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath, "Module Backup");
                //Create backup folder
                if (!Directory.Exists(backUpLocation))
                    Directory.CreateDirectory(backUpLocation);
            }

            foreach (var dllItem in dllItems)
            {
                if (dllItem.ItemValidationStatus == ImportItemStatus.AlreadyExists && dllItem.ActionToBeTaken == KEEP_CURRENT)
                    continue;

                dllItem.Process = P2Translator.GetResource("ImportProcess");

                if (P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryType.Trim().ToUpper() == "DATABASE")
                {
                    using (ModuleManagerDataContext db = new ModuleManagerDataContext(connectionString))
                    {
                        var moduleName = ModulesXmlFileData[dllItem.ItemName];
                        if (string.IsNullOrEmpty(moduleName))
                            throw new MissingFieldException("Data is not proper in Modules xml file");

                        if (dllItem.ItemValidationStatus == ImportItemStatus.AlreadyExists && dllItem.ActionToBeTaken == REPLACE)
                        {
                            AssemblyInfoHelper assemblyInfoHelper = new AssemblyInfoHelper(Path.Combine(TempFolderForCuberry, dllItem.ItemName));

                            XConfigModules xConfigModules = null;

                            if (xConfigModulesCollection.Count > 0)
                            {
                                xConfigModules = xConfigModulesCollection.Where(e => e.ModuleName.Trim().ToUpper() == moduleName.Trim().ToUpper()
                                                                && e.FileName.Trim().ToUpper() == dllItem.ItemName.Trim().ToUpper()
                                                                && e.Version == assemblyInfoHelper.AssemblyVersion).FirstOrDefault();
                            }
                            if (xConfigModules != null)
                            {
                                dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("BackupProcess");

                                XConfigModulesBackup xConfigModulesBackup = new XConfigModulesBackup();
                                xConfigModulesBackup.ModuleName = xConfigModules.ModuleName;
                                xConfigModulesBackup.FileName = xConfigModules.FileName;
                                xConfigModulesBackup.Version = xConfigModules.Version;
                                xConfigModulesBackup.AssemblyContent = xConfigModules.AssemblyContent;
                                xConfigModulesBackup.CreatedOn = DateTime.Now;
                                xConfigModulesBackup.CreatedBy = P2.Cuberry.Framework.Security.User.Current.UserID;
                                xConfigModulesBackup.EditedOn = DateTime.Now;
                                xConfigModulesBackup.EditedBy = P2.Cuberry.Framework.Security.User.Current.UserID;

                                db.XConfigModulesBackup.AddObject(xConfigModulesBackup);

                                // Now update existing module data
                                var xConfigForUpdate = (from q in db.XConfigModules
                                                        where q.ModuleName == xConfigModules.ModuleName && q.FileName == xConfigModules.FileName && q.Version == xConfigModules.Version
                                                        select q).FirstOrDefault();

                                if (xConfigForUpdate != null)
                                {
                                    xConfigModules.ModuleName = moduleName;
                                    xConfigModules.FileName = dllItem.ItemName;
                                    xConfigModules.Version = assemblyInfoHelper.AssemblyVersion;
                                    xConfigModules.AssemblyContent = File.ReadAllBytes(dllItem.FileFullName);
                                    xConfigModules.EditedOn = DateTime.Now;
                                    xConfigModules.EditedBy = P2.Cuberry.Framework.Security.User.Current.UserID;
                                    dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("ImportProcessCompleted");
                                }
                            }
                            else
                            {
                                XConfigModules newEntryInXConfigModules = new XConfigModules();
                                newEntryInXConfigModules.ModuleName = moduleName;
                                newEntryInXConfigModules.FileName = dllItem.ItemName;
                                newEntryInXConfigModules.Version = assemblyInfoHelper.AssemblyVersion;
                                newEntryInXConfigModules.AssemblyContent = File.ReadAllBytes(dllItem.FileFullName);
                                newEntryInXConfigModules.CreatedOn = DateTime.Now;
                                newEntryInXConfigModules.CreatedBy = P2.Cuberry.Framework.Security.User.Current.UserID;
                                newEntryInXConfigModules.EditedOn = DateTime.Now;
                                newEntryInXConfigModules.EditedBy = P2.Cuberry.Framework.Security.User.Current.UserID;

                                db.XConfigModules.AddObject(newEntryInXConfigModules);
                                dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("ImportProcessCompleted");
                            }
                        }
                        else if (dllItem.ItemValidationStatus == ImportItemStatus.Ok)
                        {
                            AssemblyInfoHelper assemblyInfoHelper = new AssemblyInfoHelper(Path.Combine(TempFolderForCuberry, dllItem.ItemName));

                            XConfigModules newEntryInXConfigModules = new XConfigModules();

                            newEntryInXConfigModules.ModuleName = moduleName;
                            newEntryInXConfigModules.FileName = dllItem.ItemName;
                            newEntryInXConfigModules.Version = assemblyInfoHelper.AssemblyVersion;
                            newEntryInXConfigModules.AssemblyContent = File.ReadAllBytes(dllItem.FileFullName);
                            newEntryInXConfigModules.CreatedOn = DateTime.Now;
                            newEntryInXConfigModules.CreatedBy = P2.Cuberry.Framework.Security.User.Current.UserID;
                            newEntryInXConfigModules.EditedOn = DateTime.Now;
                            newEntryInXConfigModules.EditedBy = P2.Cuberry.Framework.Security.User.Current.UserID;

                            db.XConfigModules.AddObject(newEntryInXConfigModules);
                            dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("ImportProcessCompleted");
                        }
                        db.SaveChanges();
                    }
                }
                else
                {
                    //Check is module already exists
                    if (File.Exists(Path.Combine(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath, dllItem.ItemName)))
                    {
                        dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("BackupProcess");
                        // If this module already exists at backup location then first delete it
                        if (File.Exists(Path.Combine(backUpLocation, dllItem.ItemName)))
                            File.Delete(Path.Combine(backUpLocation, dllItem.ItemName));

                        File.Move(Path.Combine(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath, dllItem.ItemName), Path.Combine(backUpLocation, dllItem.ItemName));
                    }

                    File.Copy(Path.Combine(TempFolderForCuberry, dllItem.ItemName), Path.Combine(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath, dllItem.ItemName), true);

                    if (!string.IsNullOrEmpty(ModulesLocation))
                        File.Copy(Path.Combine(TempFolderForCuberry, dllItem.ItemName), Path.Combine(ModulesLocation, dllItem.ItemName),true);

                    dllItem.Process = dllItem.Process + SPACE_DOTS + P2Translator.GetResource("ImportProcessCompleted");
                }
            }

            return true;
        }

        private bool ImportDatabaseItems()
        {
            XMLFileProcessor xMLFileProcessor = new XMLFileProcessor(GetMeConnectionString());
            xMLFileProcessor.ProcessCreateXMLFile(Path.Combine(TempFolderForCuberry, "Create Table.xml"), this.ImportList);
            xMLFileProcessor.ProcessUpdateXMLFile(Path.Combine(TempFolderForCuberry, "Update Table.xml"), this.ImportList);

            return true;
        }

        private bool DoValidationForAssemblies()
        {
            bool conflictFound = false;

            IEnumerable<ModulesImport> dllItems = ImportList.Where(e => e.ItemType == ImportItemType.Dll);

            List<XConfigModules> xConfigModules = null;

            if (P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryType.Trim().ToUpper() == "DATABASE")
            {
                string connectionString = ConfigurationSetUp.GetEntConnectionString("Business", Properties.Settings.Default.EntityResources);
                using (ModuleManagerDataContext db = new ModuleManagerDataContext(connectionString))
                {
                    xConfigModules = (from tran in db.XConfigModules
                                     select tran).ToList();
                }
            }

            foreach (var dllItem in dllItems)
            {
                if (P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryType.Trim().ToUpper() == "DATABASE")
                {
                    if (xConfigModules == null)
                        continue;

                    AssemblyInfoHelper assemblyInfoHelper = new AssemblyInfoHelper(Path.Combine(TempFolderForCuberry, dllItem.ItemName));
                    XConfigModules singleModule = xConfigModules.Where(e => e.FileName.Trim().ToUpper() == dllItem.ItemName.Trim().ToUpper() 
                                                    && e.Version == assemblyInfoHelper.AssemblyVersion).FirstOrDefault();

                    if (singleModule != null)
                    {
                        conflictFound = true;
                        dllItem.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        dllItem.Process = P2Translator.GetResource("DLLAlreadyExists");
                    }
                    else
                        dllItem.ItemValidationStatus = ImportItemStatus.Ok;
                }
                else
                {
                    if (string.IsNullOrEmpty(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath))
                        throw new MissingFieldException("Modules Repository Path was not defined in DB configuration");

                    if (File.Exists(Path.Combine(P2.Cuberry.Framework.Helper.ModuleRepository.ModulesRepositoryPath, dllItem.ItemName)))
                    {
                        conflictFound = true;
                        dllItem.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        dllItem.Process = P2Translator.GetResource("DLLAlreadyExists");
                    }
                    else
                    {
                        dllItem.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
            }
            return conflictFound;
        }

        private bool DoValidationForDBObjects()
        {
            bool conflictFound = false;

            string connectionString = GetMeConnectionString();
            if (string.IsNullOrEmpty(connectionString))
                throw new MissingFieldException("Could not get connection string from cubbery config file");

            var DBName = GetMeDBName(connectionString);

            Server server = new Server();
            server.ConnectionContext.ConnectionString = connectionString;
            server.ConnectionContext.Connect();

            if (server.Databases[DBName] == null)
                throw new MissingObjectException("Cuberry database does not exists in DB server");
            
            Database database = server.Databases[DBName];

            IEnumerable<ModulesImport> dbObjectItems = ImportList.Where(e => e.ItemType == ImportItemType.Xml);

            foreach (ModulesImport modulesImport in dbObjectItems)
            {
                if (modulesImport.ActionType == TABLE_CREATION)
                {
                    Table tableToCreate = database.Tables[modulesImport.ItemName];
                    if (tableToCreate != null)
                    {
                        conflictFound = true;
                        modulesImport.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        modulesImport.Process = P2Translator.GetResource("TableAlreadyExists");
                    }
                    else
                    {
                        modulesImport.Process = string.Empty;
                        modulesImport.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
                else if (modulesImport.ActionType == TABLE_UPDATE)
                {
                    Table tableToUpdate = database.Tables[modulesImport.ItemName];
                    if (tableToUpdate == null)
                    {
                        conflictFound = true;
                        modulesImport.ItemValidationStatus = ImportItemStatus.TableDoesNotExists;
                        modulesImport.Process = P2Translator.GetResource("TableDoesNotExists");
                    }
                    else
                    {
                        modulesImport.Process = string.Empty;
                        modulesImport.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
                else if (modulesImport.ActionType == VIEW_CREATION)
                {
                    View view = database.Views[modulesImport.ItemName];
                    if (view != null)
                    {
                        conflictFound = true;
                        modulesImport.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        modulesImport.Process = P2Translator.GetResource("This ") + P2Translator.GetResource("View") + " " + P2Translator.GetResource("AlreadyExists");
                    }
                    else
                    {
                        modulesImport.Process = string.Empty;
                        modulesImport.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
                else if (modulesImport.ActionType == SP_CREATION)
                {
                    StoredProcedure storedProcedure = database.StoredProcedures[modulesImport.ItemName];
                    if (storedProcedure != null)
                    {
                        conflictFound = true;
                        modulesImport.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        modulesImport.Process = P2Translator.GetResource("This ") + P2Translator.GetResource("SP") + " " + P2Translator.GetResource("AlreadyExists");
                    }
                    else
                    {
                        modulesImport.Process = string.Empty;
                        modulesImport.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
                else if (modulesImport.ActionType == FUNCTION_CREATION)
                {
                    UserDefinedFunction udf = database.UserDefinedFunctions[modulesImport.ItemName];
                    if (udf != null)
                    {
                        conflictFound = true;
                        modulesImport.ItemValidationStatus = ImportItemStatus.AlreadyExists;
                        modulesImport.Process = P2Translator.GetResource("This ") + P2Translator.GetResource("Function") + " " + P2Translator.GetResource("AlreadyExists");
                    }
                    else
                    {
                        modulesImport.Process = string.Empty;
                        modulesImport.ItemValidationStatus = ImportItemStatus.Ok;
                    }
                }
            }

            if (server.ConnectionContext.IsOpen)
                server.ConnectionContext.Cancel();

            return conflictFound;
        }

        private static string GetMeDBName(string conenctionString)
        {
            IEnumerable<string> conenctionStringItems = conenctionString.Split(';').Select(x => x.Trim());

            foreach (var item in conenctionStringItems)
            {
                if (item.Contains("Initial Catalog"))
                {
                    if (item.IndexOf("=") != -1)
                        return item.Substring(item.IndexOf("=") + 1);
                }
            }
            return string.Empty;
        }

        private static string GetMeConnectionString()
        {
            string configFileName = System.Reflection.Assembly.GetEntryAssembly().Location + ".config";

            XmlDocument doc = new XmlDocument();

            doc.Load(Path.Combine(configFileName));

            XmlNamespaceManager manager = new XmlNamespaceManager(doc.NameTable);
            manager.AddNamespace("bindings", "urn:schemas-microsoft-com:asm.v1");
            XmlNode root = doc.DocumentElement;

            XmlNode connectionNode = doc.SelectSingleNode("//configuration//connectionStrings//add[@name='Business']");
            
            XmlAttribute connectionAttribute = connectionNode.Attributes["connectionString"];

            return connectionAttribute.Value;
        }


        #region Property Changed

        public event PropertyChangedEventHandler PropertyChanged;

        private void OnPropertyChanged(string propertyName)
        {
            PropertyChangedEventHandler Handler = PropertyChanged;
            if (Handler != null)
                Handler(this, new PropertyChangedEventArgs(propertyName));
        }

        public void OnAllPropertiesChanged()
        {
            OnPropertyChanged("ItemName");
            OnPropertyChanged("ActionType");
            OnPropertyChanged("ActionToBeTaken");
            OnPropertyChanged("Process");
            OnPropertyChanged("StatusImage");
            OnPropertyChanged("ItemValidationStatus");
            OnPropertyChanged("ItemType");
            OnPropertyChanged("FileFullName");
            OnPropertyChanged("ImportList");
        }

        #endregion

        #region Validator

        public override P2Validator Validator
        {
            get
            {
                if (_validator == null)
                {
                    _validator = new P2Validator(Properties.Settings.Default.ModuleName, this.EntityName, "DialogName", this);
                }
                return _validator;
            }
        }

        #endregion


    }

    public enum ImportItemStatus
    {
        NotValidated,
        Ok,
        AlreadyExists,
        TableDoesNotExists
    }

    public enum ImportItemType
	{
        Dll,
        Xml
	}
}
